﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Text.RegularExpressions; /* Agregada por mi */
using PolimericosABM.data;
using PolimericosABM.services;

namespace PolimericosABM
{
    public partial class frmAddPoli : Form
    {
        // String que representa la expresión regular para validar
        // que el dato en el combobox cbxLinea tenga formato correcto
        public const string ExprRegLinea = @"[125]{1}[a-zA-Z]{4}[1-9]{1}";

        public const string ExprRegEstructura = @"^[0-9]+$";

        private PolimeroService _service = new PolimeroService();

        public frmAddPoli()
        {
            InitializeComponent();
            cbxCadenaTipo.SelectedIndex = 0;
            cbxRegion.SelectedIndex = 0;
            cbxFase.SelectedIndex = 0;
        }

        /// <summary>
        /// Valida los datos ingresados por el usuario
        /// </summary>
        /// <returns>True si no hay error</returns>
        private bool ValidarTodo()
        {
            bool error = false;
            /*
            Chequeo de datos cargados correctamente en el formulario
             */
            eppMain.Clear();

            if (!ValidarLinea(cbxLinea.Text))
            {
                eppMain.SetError(cbxLinea, "Codificación de nombre de línea #AABB#:\n" +
                                           "#: número del tipo de linea (1, 2 o 5)\n" +
                                           "AA: 2 letras codificando lugar de origen.\n" +
                                           "BB: 2 letras codificando lugar de destino.\n" +
                                           "#: número de línea.");
                error = true;
            }

            if (!ValidarEstructura(cbxEstructura.Text))
            {
                eppMain.SetError(cbxEstructura, "Sólo se pueden agregar caracteres numéricos (0-9) en el campo Estructura.");
                error = true;
            }

            if (mskdtxtBxCadenaNum.Text == "")
            {
                eppMain.SetError(mskdtxtBxCadenaNum, "Ingrese un valor válido (no vacío) en el campo Cadena N°.");
                error = true;
            }

            if (cbxMarca.Text == "")
            {
                eppMain.SetError(cbxMarca, "Ingrese un valor válido (no vacío) en el campo Marca.");
                error = true;
            }

            /*
            if (dateTimePickerInstalado.Checked)
            {
                if (dateTimePickerInstalado.Format == DateTimePickerFormat.Custom)
                {
                    error = true;
                    // Quiero poner el color del DateTimePicker en rojo, pero no anda
                    // hay que hacer otro maneje
                    dateTimePickerInstalado.BackColor = Color.Red;
                    dateTimePickerInstalado.ForeColor = Color.Red;
                    dateTimePickerInstalado.CalendarTitleBackColor = Color.Red;
                    dateTimePickerInstalado.CalendarForeColor = Color.Blue;
                }
            }
            if (dateTimePickerReemplazo.Checked)
            {
                if (dateTimePickerReemplazo.Format == DateTimePickerFormat.Custom)
                {
                    error = true;
                    // Quiero poner el color del DateTimePicker en rojo, pero no anda
                    // hay que hacer otro maneje
                    dateTimePickerReemplazo.BackColor = Color.Red;
                    dateTimePickerReemplazo.ForeColor = Color.Red;
                    dateTimePickerReemplazo.CalendarTitleBackColor = Color.Red;
                    dateTimePickerReemplazo.CalendarForeColor = Color.Blue;
                }
            }
            */
            return !error;
        }

        private void CargarMarcas()
        {
            // Con el siguiente try-catch obtengo las marcas registradas en la base de datos
            try
            {
                cbxMarca.ResetText();
                cbxMarca.Items.Clear();
                List<string> marcas = _service.GetMarcas();

                cbxMarca.Items.AddRange(marcas.ToArray());
                if (cbxMarca.Items.Count > 0)
                {
                    cbxMarca.SelectedIndex = 0;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error al intentar abrir la base", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnCargarLineas_Click(object sender, EventArgs e)
        {
            try
            {
                cbxLinea.ResetText();
                cbxLinea.Items.Clear();
                string region = cbxRegion.SelectedItem.ToString();
                List<string> lineas = _service.GetLineas(region);

                cbxLinea.Items.AddRange(lineas.ToArray());
                if (cbxLinea.Items.Count > 0)
                {
                    cbxLinea.SelectedIndex = 0;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error al intentar abrir la base", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void frmAddPoli_Load(object sender, EventArgs e)
        {
            // Con el siguiente try-catch obtengo las marcas registradas en la base de datos
            CargarMarcas();

            // TextBox con máscara
            mskdtxtBxCadenaNum.Mask = "0";
            mskdtxtBxCadenaNum.MaskInputRejected += new MaskInputRejectedEventHandler(mskdtxtBxCadenaNum_MaskInputRejected);
            mskdtxtBxCadenaNum.KeyDown += new KeyEventHandler(mskdtxtBxCadenaNum_KeyDown);

            // Seteo los DateTimePicker con un valor vacio
            dateTimePickerInstalado.CustomFormat = " ";
            dateTimePickerInstalado.Format = DateTimePickerFormat.Custom;
            dateTimePickerReemplazo.CustomFormat = " ";
            dateTimePickerReemplazo.Format = DateTimePickerFormat.Custom;
        }

        private void btnCargaData_Click(object sender, EventArgs e)
        {
            if (!ValidarTodo()) 
            {
                MessageBox.Show("Los campos en rojo son obligatorios.\n"+
                                "No se ha agregado el polimérico a la base de datos\n" +
                                "porque los datos no son válidos o están incompletos.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            Polimero polimero = new Polimero();

            polimero.Region = cbxRegion.SelectedItem.ToString().ToUpper();
            // Uso el Text y no el SelectedItem porque este combobox tiene la opción de editar el texto
            polimero.Linea = cbxLinea.Text.ToString();
            polimero.Estructura = Convert.ToInt32(cbxEstructura.Text.ToString());
            polimero.Fase = Convert.ToInt16(cbxFase.SelectedItem.ToString());
            polimero.TipoCadena = cbxCadenaTipo.SelectedItem.ToString();
            polimero.NumeroCadena = Convert.ToInt16(mskdtxtBxCadenaNum.Text.ToString());
            polimero.Marca = cbxMarca.Text.ToString().ToUpper();
            polimero.Modelo = cbxModelo.Text.ToString();
            polimero.Aro_Frio = Convert.ToBoolean(chckbxAroLFrio.Checked);
            polimero.Aro_Caliente = Convert.ToBoolean(chckbxAroLCaliente.Checked);
            polimero.Aro_Linea_Frio = Convert.ToBoolean(chckbxAroLineaLFrio.Checked);
            polimero.Aro_Linea_Caliente = Convert.ToBoolean(chckbxAroLineaLCaliente.Checked);

            if (dateTimePickerInstalado.Checked)
            {
                polimero.Fecha_Instalado = dateTimePickerInstalado.Value.Date;
            }

            if (dateTimePickerReemplazo.Checked)
            {
                polimero.Fecha_Reemplazo = dateTimePickerReemplazo.Value.Date;    
            }
            
            polimero.Observaciones = txtBxObservaciones.Text;

            // Consultar si existe un polimérico en esa ubicación
            if (_service.ExistePolimero(polimero))
            {
                MessageBox.Show("Ya existe un polimérico en esa ubicación. Si se efectúo un reemplazo, por favor primero actualice los datos del polimérico que ha sido reemplazado.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            _service.AgregarPolimero(polimero);

            CargarMarcas();

            MessageBox.Show("Se agrego el polimérico con exito!", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void btnSalir_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
        }

        /* Cargar estructuras
        Cargar por todas las estructuras de una línea en una determinada región
        NOTA: una línea puede estar en más de una región
        p.e.: la línea 5EZHE1 (5 por 500kV, EZ por Ezeiza y HE por Henderson) es una línea
        que pasa tanto por la región Metropolitana como por la del Sur
        */
        private void btnCargarEstructuras_Click(object sender, EventArgs e)
        {
            // Si hay algún elemento en el combobox de líneas o si se ha escrito algo en el mismo
            if (cbxLinea.Items.Count != 0 | cbxLinea.Text.Length != 0)
            {
                try
                {
                    cbxEstructura.ResetText();
                    cbxEstructura.Items.Clear();
                    string region = cbxRegion.SelectedItem.ToString();
                    // Uso el Text y no el SelectedItem porque este combobox tiene la opción de editar el texto
                    string linea = cbxLinea.Text.ToString();
                    List<string> estructuras = _service.GetEstructuras(region, linea);

                    cbxEstructura.Items.AddRange(estructuras.ToArray());
                    if (cbxEstructura.Items.Count > 0)
                    {
                        cbxEstructura.SelectedIndex = 0;
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error al intentar abrir la base", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else 
            {
                MessageBox.Show("No hay valor válido en Línea.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        // Cargar los modelos según la marca
        private void btnCargarModelos_Click(object sender, EventArgs e)
        {
            // Si hay algún elemento en el combobox de líneas o si se ha escrito algo en el mismo
            if (cbxMarca.Items.Count != 0 && cbxMarca.Text.Length != 0)
            {
                try
                {
                    cbxModelo.ResetText();
                    cbxModelo.Items.Clear();
                    // Uso el Text y no el SelectedItem porque este combobox tiene la opción de editar el texto
                    string marca = cbxMarca.Text.ToString();
                    List<string> modelos = _service.GetModelos(marca);

                    cbxModelo.Items.AddRange(modelos.ToArray());
                    if (cbxModelo.Items.Count > 0)
                    {
                        cbxModelo.SelectedIndex = 0;
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error al intentar abrir la base", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                MessageBox.Show("No hay valor válido en Marca.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        void mskdtxtBxCadenaNum_MaskInputRejected(object sender, MaskInputRejectedEventArgs e)
        {
            if (mskdtxtBxCadenaNum.MaskFull)
            {
                toolTipmskdtxtBxCadenaNum.ToolTipTitle = "Entrada rechazada - Exceso de datos";
                toolTipmskdtxtBxCadenaNum.Show("No se puede introducir ningún dato más en el campo Cadena N°.\nEliminar algunos caracteres con el fin de insertar más datos.", mskdtxtBxCadenaNum, 0, -20, 5000);
            }
            else if (e.Position == mskdtxtBxCadenaNum.Mask.Length)
            {
                toolTipmskdtxtBxCadenaNum.ToolTipTitle = "Entrada rechazada - Final del campo";
                toolTipmskdtxtBxCadenaNum.Show("No se pueden agregar caracteres adicionales\nal final del campo Cadena N°.", mskdtxtBxCadenaNum, 0, -20, 5000);
            }
            else
            {
                toolTipmskdtxtBxCadenaNum.ToolTipTitle = "Entrada rechazada";
                toolTipmskdtxtBxCadenaNum.Show("Sólo se pueden agregar caracteres numéricos (0-9) en el campo Cadena N°.", mskdtxtBxCadenaNum, 0, -20, 5000);
            }
        }

        void mskdtxtBxCadenaNum_KeyDown(object sender, KeyEventArgs e)
        {
            // The balloon tip is visible for five seconds; if the user types any data before it disappears, collapse it ourselves.
            toolTipmskdtxtBxCadenaNum.Hide(mskdtxtBxCadenaNum);
        }

        private void dateTimePickerInstalado_ValueChanged(object sender, EventArgs e)
        {
            // Recupero el formato de fecha cuando hay algún cambio en el control
            dateTimePickerInstalado.Format = DateTimePickerFormat.Short;
        }

        private void dateTimePickerReemplazo_ValueChanged(object sender, EventArgs e)
        {
            // Recupero el formato de fecha cuando hay algún cambio en el control
            dateTimePickerReemplazo.Format = DateTimePickerFormat.Short;
        }

        private void cbxRegion_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Si cambia el valor del indice limpio los combobox cbxLinea y cbxEstructura
            cbxLinea.Items.Clear();
            cbxLinea.Text = "";
            //cbxLinea.Refresh();
            cbxEstructura.Items.Clear();
            cbxEstructura.Text = "";
            cbxLinea.Refresh();
        }

        public bool ValidarLinea(string linea)
        {
            if (linea != null)
            {
                return Regex.IsMatch(linea, ExprRegLinea);
            }
            else
            {
                return false;
            }
        }

        public bool ValidarEstructura(string estructura)
        {
            if (estructura != null)
            {
                return Regex.IsMatch(estructura, ExprRegEstructura);
            }
            else
            {
                return false;
            }
        }
    }
}
